{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rX8mhOLljYeM"
      },
      "source": [
        "##### Copyright 2019 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3wF5wszaj97Y"
      },
      "source": [
        "# 初学者的 TensorFlow 2.0 教程"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "04QgGZc9bF5D"
      },
      "source": [
        "此简短介绍使用 [Keras](https://tensorflow.google.cn/guide/keras/overview) 进行以下操作：\n",
        "\n",
        "1. 加载一个预构建的数据集。\n",
        "2. 构建对图像进行分类的神经网络机器学习模型。\n",
        "3. 训练此神经网络。\n",
        "4. 评估模型的准确率。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hiH7AC-NTniF"
      },
      "source": [
        "这是一个 [Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb) 笔记本文件。 Python程序可以直接在浏览器中运行，这是学习 Tensorflow 的绝佳方式。想要学习该教程，请点击此页面顶部的按钮，在Google Colab中运行笔记本。\n",
        "\n",
        "1. 在 Colab中, 连接到Python运行环境： 在菜单条的右上方, 选择 *CONNECT*。\n",
        "2. 运行所有的代码块: 选择 *Runtime* &gt; *Run all*。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nnrWf3PCEzXL"
      },
      "source": [
        "## 设置 TensorFlow\n",
        "\n",
        "首先将 TensorFlow 导入到您的程序："
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0trJmd6DjqBZ"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7NAbSZiaoJ4z"
      },
      "source": [
        "如果您在自己的开发环境而不是 [Colab](https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/quickstart/beginner.ipynb) 中操作，请参阅设置 TensorFlow 以进行开发的[安装指南](https://tensorflow.google.cn/install)。\n",
        "\n",
        "注：如果您使用自己的开发环境，请确保您已升级到最新的 `pip` 以安装 TensorFlow 2 软件包。有关详情，请参阅[安装指南](https://tensorflow.google.cn/install)。\n",
        "\n",
        "## 加载数据集\n",
        "\n",
        "加载并准备 [MNIST 数据集](http://yann.lecun.com/exdb/mnist/)。将样本数据从整数转换为浮点数："
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7FP5258xjs-v"
      },
      "outputs": [],
      "source": [
        "mnist = tf.keras.datasets.mnist\n",
        "\n",
        "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
        "x_train, x_test = x_train / 255.0, x_test / 255.0"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BPZ68wASog_I"
      },
      "source": [
        "## 构建机器学习模型\n",
        "\n",
        "通过堆叠层来构建 `tf.keras.Sequential` 模型。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "h3IKyzTCDNGo"
      },
      "outputs": [],
      "source": [
        "model = tf.keras.models.Sequential([\n",
        "  tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
        "  tf.keras.layers.Dense(128, activation='relu'),\n",
        "  tf.keras.layers.Dropout(0.2),\n",
        "  tf.keras.layers.Dense(10)\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l2hiez2eIUz8"
      },
      "source": [
        "对于每个样本，模型都会返回一个包含 [logits](https://developers.google.com/machine-learning/glossary#logits) 或 [log-odds](https://developers.google.com/machine-learning/glossary#log-odds) 分数的向量，每个类一个。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OeOrNdnkEEcR"
      },
      "outputs": [],
      "source": [
        "predictions = model(x_train[:1]).numpy()\n",
        "predictions"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tgjhDQGcIniO"
      },
      "source": [
        "`tf.nn.softmax` 函数将这些 logits 转换为每个类的*概率*： "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zWSRnQ0WI5eq"
      },
      "outputs": [],
      "source": [
        "tf.nn.softmax(predictions).numpy()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "he5u_okAYS4a"
      },
      "source": [
        "注：可以将 `tf.nn.softmax` 烘焙到网络最后一层的激活函数中。虽然这可以使模型输出更易解释，但不建议使用这种方式，因为在使用 softmax 输出时不可能为所有模型提供精确且数值稳定的损失计算。 "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hQyugpgRIyrA"
      },
      "source": [
        "使用 `losses.SparseCategoricalCrossentropy` 为训练定义损失函数，它会接受 logits 向量和 `True` 索引，并为每个样本返回一个标量损失。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "RSkzdv8MD0tT"
      },
      "outputs": [],
      "source": [
        "loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SfR4MsSDU880"
      },
      "source": [
        "此损失等于 true 类的负对数概率：如果模型确定类正确，则损失为零。\n",
        "\n",
        "这个未经训练的模型给出的概率接近随机（每个类为 1/10），因此初始损失应该接近 `-tf.math.log(1/10) ~= 2.3`。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "NJWqEVrrJ7ZB"
      },
      "outputs": [],
      "source": [
        "loss_fn(y_train[:1], predictions).numpy()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ada44eb947d4"
      },
      "source": [
        "在开始训练之前，使用 Keras `Model.compile` 配置和编译模型。将 [`optimizer`](https://tensorflow.google.cn/api_docs/python/tf/keras/optimizers) 类设置为 `adam`，将 `loss` 设置为您之前定义的 `loss_fn` 函数，并通过将 `metrics` 参数设置为 `accuracy` 来指定要为模型评估的指标。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9foNKHzTD2Vo"
      },
      "outputs": [],
      "source": [
        "model.compile(optimizer='adam',\n",
        "              loss=loss_fn,\n",
        "              metrics=['accuracy'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ix4mEL65on-w"
      },
      "source": [
        "## 训练并评估模型\n",
        "\n",
        "使用 `Model.fit` 方法调整您的模型参数并最小化损失： "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "y7suUbJXVLqP"
      },
      "outputs": [],
      "source": [
        "model.fit(x_train, y_train, epochs=5)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4mDAAPFqVVgn"
      },
      "source": [
        "`Model.evaluate` 方法通常在 \"[Validation-set](https://developers.google.com/machine-learning/glossary#validation-set)\" 或 \"[Test-set](https://developers.google.com/machine-learning/glossary#test-set)\" 上检查模型性能。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "F7dTAzgHDUh7"
      },
      "outputs": [],
      "source": [
        "model.evaluate(x_test,  y_test, verbose=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "T4JfEh7kvx6m"
      },
      "source": [
        "现在，这个照片分类器的准确度已经达到 98%。想要了解更多，请阅读 [TensorFlow 教程](https://tensorflow.google.cn/tutorials/)。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Aj8NrlzlJqDG"
      },
      "source": [
        "如果您想让模型返回概率，可以封装经过训练的模型，并将 softmax 附加到该模型："
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "rYb6DrEH0GMv"
      },
      "outputs": [],
      "source": [
        "probability_model = tf.keras.Sequential([\n",
        "  model,\n",
        "  tf.keras.layers.Softmax()\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cnqOZtUp1YR_"
      },
      "outputs": [],
      "source": [
        "probability_model(x_test[:5])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-47O6_GLdRuT"
      },
      "source": [
        "## 结论\n",
        "\n",
        "恭喜！您已经利用 [Keras](https://tensorflow.google.cn/guide/keras/overview) API 借助预构建数据集训练了一个机器学习模型。\n",
        "\n",
        "有关使用 Keras 的更多示例，请查阅[教程](https://tensorflow.google.cn/tutorials/keras/)。要详细了解如何使用 Keras 构建模型，请阅读[指南](https://tensorflow.google.cn/guide/keras)。如果您想详细了解如何加载和准备数据，请参阅有关[图像数据加载](https://tensorflow.google.cn/tutorials/load_data/images)或 [CSV 数据加载](https://tensorflow.google.cn/tutorials/load_data/csv)的教程。\n"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "rX8mhOLljYeM"
      ],
      "name": "beginner.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
